package com.lagou.handler;

import com.lagou.bean.ApplicationContextFactory;
import com.lagou.client.RPCConsumer;
import com.lagou.pojo.RpcRequest;
import com.lagou.pojo.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;

/**
 *  自定义事件处理器
 */
public class UserClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    //1.定义成员变量
    private ChannelHandlerContext context; //事件处理器上下文对象 (存储handler信息,写操作)
    private Object result; // 记录服务器返回的数据
    private RpcRequest request; //记录将要返送给服务器的数据
    private long responseTime;
    private String host;
    private Object proxyObject;

    private Timer timer;

    // 监测如果服务器断开连接，则客户端也断开
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("监测到服务端连接关闭");
        RPCConsumer rpcConsumer = (RPCConsumer) ApplicationContextFactory.applicationContext.getBean(RPCConsumer.class);
        rpcConsumer.removeHandler(host);
        ctx.close();
    }

    //2.实现channelActive  客户端和服务器连接时,该方法就自动执行
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //初始化ChannelHandlerContext
        this.context = ctx;
    }


    //3.实现channelRead 当我们读到服务器数据,该方法自动执行
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 每次接收请求时重置定时器
        autoTimer();
        long startTime = System.currentTimeMillis();

        //将读到的服务器的数据msg ,设置为成员变量的值
        if (msg instanceof RpcResponse) {
            RpcResponse response = (RpcResponse) msg;
            result = response.getObject();
        }

        long random = (long) (Math.random() * 500);
        System.out.println("随机休眠" + random + "毫秒");
        Thread.sleep(random);

        responseTime = System.currentTimeMillis() - startTime;
//        zkClient.creatTempPath(CommonNode.serverNode + CommonNode.responseTimeNode, responseTime + "");
        notify();
    }

    //4.将客户端的数写到服务器
    public synchronized Object call() throws Exception {
        //context给服务器写数据
        context.writeAndFlush(request);
        wait();
        return result;
    }

    //5.设置参数的方法
    public void setParam(RpcRequest request){
        this.request = request;
    }

    /**
     * 每隔5秒如果没有请求进入方法，则把ResponseTime标记为0。如果有请求，则清理上一个定时器，重新定时
     */
    private void autoTimer() {
        if (timer != null) {
            timer.cancel();
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    responseTime = 0;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 5000);
    }

    public long getResponseTime() {
        return responseTime;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public Object getProxyObject() {
        return proxyObject;
    }

    public void setProxyObject(Object proxyObject) {
        this.proxyObject = proxyObject;
    }
}
